by the CPU. Also generally beef up robustness of VMXON instruction.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
}
else
{
- eax = (IA32_FEATURE_CONTROL_MSR_LOCK |
- IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_OUTSIDE_SMX |
- IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_INSIDE_SMX);
+ eax = IA32_FEATURE_CONTROL_MSR_LOCK;
+ eax |= IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_OUTSIDE_SMX;
+ if ( test_bit(X86_FEATURE_SMXE, &boot_cpu_data.x86_capability) )
+ eax |= IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_INSIDE_SMX;
wrmsr(IA32_FEATURE_CONTROL_MSR, eax, 0);
}
- if ( !tboot_in_measured_env() &&
- !(eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_OUTSIDE_SMX) )
- {
- printk("VMX only allowed in SMX but SMX not active.\n");
- return 0;
- }
-
vmx_init_vmcs_config();
INIT_LIST_HEAD(&this_cpu(active_vmcs_list));
struct bug_frame bug;
struct bug_frame_str bug_str;
char *filename, *predicate, *eip = (char *)regs->eip;
+ unsigned long fixup;
int id, lineno;
DEBUGGER_trap_entry(TRAP_invalid_op, regs);
predicate, filename, lineno);
die:
+ if ( (fixup = search_exception_table(regs->eip)) != 0 )
+ {
+ regs->eip = fixup;
+ return;
+ }
DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
show_execution_state(regs);
panic("FATAL TRAP: vector = %d (invalid opcode)\n", TRAP_invalid_op);
__vmwrite(field, __vmread(field) & ~(1UL << bit));
}
-static inline void __vmxoff (void)
+static inline void __vmxoff(void)
{
- __asm__ __volatile__ ( VMXOFF_OPCODE
- ::: "memory");
+ asm volatile (
+ VMXOFF_OPCODE
+ : : : "memory" );
}
-static inline int __vmxon (u64 addr)
+static inline int __vmxon(u64 addr)
{
int rc;
- __asm__ __volatile__ ( VMXON_OPCODE
- MODRM_EAX_06
- /* CF==1 or ZF==1 --> rc = -1 */
- "setna %b0 ; neg %0"
- : "=q" (rc)
- : "0" (0), "a" (&addr)
- : "memory");
+ asm volatile (
+ "1: " VMXON_OPCODE MODRM_EAX_06 "\n"
+ " setna %b0 ; neg %0\n" /* CF==1 or ZF==1 --> rc = -1 */
+ "2:\n"
+ ".section .fixup,\"ax\"\n"
+ "3: not %0 ; jmp 2b\n" /* #UD --> rc = -1 */
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " "__FIXUP_ALIGN"\n"
+ " "__FIXUP_WORD" 1b,3b\n"
+ ".previous\n"
+ : "=q" (rc)
+ : "0" (0), "a" (&addr)
+ : "memory");
return rc;
}